{
unsigned long error = 0;
- if (!NONPRIV_OP(cmd) && current->domain != xenoprof_primary_profiler) {
+ if (!NONPRIV_OP(cmd) && current->domain->domain_id !=0) {
gdprintk(XENLOG_INFO, "xen perfmon: "
"dom %d denied privileged operation %ld\n",
current->domain->domain_id, cmd);
///////////////////////////////////////////////////////////////////////////
// glue methods for xenoprof and perfmon.
int
-xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type)
+xenoprof_arch_init(int *num_events, char *cpu_type)
{
*num_events = 0;
strlcpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE);
-
- *is_primary = 0;
- if (xenoprof_primary_profiler == NULL) {
- /* For now, only dom0 can be the primary profiler */
- if (current->domain->domain_id == 0) {
- *is_primary = 1;
- }
- } else if (xenoprof_primary_profiler == current->domain)
- *is_primary = 1;
return 0;
}
#include "op_counter.h"
#include "op_x86_model.h"
+struct op_counter_config counter_config[OP_MAX_COUNTER];
+
static struct op_x86_model_spec const * model;
static struct op_msrs cpu_msrs[NR_CPUS];
static unsigned long saved_lvtpc[NR_CPUS];
-#define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1)
-extern int active_domains[MAX_OPROF_DOMAINS];
-extern unsigned int adomains;
-extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS];
-extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE];
-extern int is_active(struct domain *d);
-extern int active_id(struct domain *d);
-extern int is_profiled(struct domain *d);
-
+static char *cpu_type;
+extern int is_active(struct domain *d);
static int nmi_callback(struct cpu_user_regs *regs, int cpu)
{
}
-struct op_counter_config counter_config[OP_MAX_COUNTER];
-
-static int __init p4_init(char * cpu_type)
+static int __init p4_init(char ** cpu_type)
{
__u8 cpu_model = current_cpu_data.x86_model;
}
#ifndef CONFIG_SMP
- strlcpy (cpu_type, "i386/p4", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/p4", XENOPROF_CPU_TYPE_SIZE);
model = &op_p4_spec;
return 1;
#else
switch (smp_num_siblings) {
case 1:
- strlcpy (cpu_type, "i386/p4",
- XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/p4";
model = &op_p4_spec;
return 1;
case 2:
- strlcpy (cpu_type, "i386/p4-ht",
- XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/p4-ht";
model = &op_p4_ht2_spec;
return 1;
}
}
-static int __init ppro_init(char *cpu_type)
+static int __init ppro_init(char ** cpu_type)
{
__u8 cpu_model = current_cpu_data.x86_model;
return 0;
}
else if (cpu_model == 15)
- strlcpy (cpu_type, "i386/core_2", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/core_2";
else if (cpu_model == 14)
- strlcpy (cpu_type, "i386/core", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/core";
else if (cpu_model == 9)
- strlcpy (cpu_type, "i386/p6_mobile", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/p6_mobile";
else if (cpu_model > 5)
- strlcpy (cpu_type, "i386/piii", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/piii";
else if (cpu_model > 2)
- strlcpy (cpu_type, "i386/pii", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/pii";
else
- strlcpy (cpu_type, "i386/ppro", XENOPROF_CPU_TYPE_SIZE);
+ *cpu_type = "i386/ppro";
model = &op_ppro_spec;
return 1;
}
-int nmi_init(int *num_events, int *is_primary, char *cpu_type)
+static int __init nmi_init(void)
{
__u8 vendor = current_cpu_data.x86_vendor;
__u8 family = current_cpu_data.x86;
- int prim = 0;
if (!cpu_has_apic) {
- printk("xenoprof: Initialization failed. No apic.\n");
+ printk("xenoprof: Initialization failed. No APIC\n");
return -ENODEV;
}
- if (xenoprof_primary_profiler == NULL) {
- /* For now, only dom0 can be the primary profiler */
- if (current->domain->domain_id == 0) {
- xenoprof_primary_profiler = current->domain;
- prim = 1;
- }
- }
-
switch (vendor) {
case X86_VENDOR_AMD:
/* Needs to be at least an Athlon (or hammer in 32bit mode) */
return -ENODEV;
case 6:
model = &op_athlon_spec;
- strlcpy (cpu_type, "i386/athlon",
- XENOPROF_CPU_TYPE_SIZE);
+ cpu_type = "i386/athlon";
break;
case 0xf:
model = &op_athlon_spec;
- /* Actually it could be i386/hammer too, but give
- user space an consistent name. */
- strlcpy (cpu_type, "x86-64/hammer",
- XENOPROF_CPU_TYPE_SIZE);
+ /* Actually it could be i386/hammer too, but
+ give user space an consistent name. */
+ cpu_type = "x86-64/hammer";
break;
}
break;
switch (family) {
/* Pentium IV */
case 0xf:
- if (!p4_init(cpu_type))
+ if (!p4_init(&cpu_type))
return -ENODEV;
break;
/* A P6-class processor */
case 6:
- if (!ppro_init(cpu_type))
+ if (!ppro_init(&cpu_type))
return -ENODEV;
break;
return -ENODEV;
}
- *num_events = model->num_counters;
- *is_primary = prim;
-
return 0;
}
+__initcall(nmi_init);
+
+int xenoprof_arch_init(int *num_events, char *_cpu_type)
+{
+ if (cpu_type == NULL)
+ return -ENODEV;
+ *num_events = model->num_counters;
+ strlcpy(_cpu_type, cpu_type, XENOPROF_CPU_TYPE_SIZE);
+ return 0;
+}
/* Lock protecting the following global state */
static DEFINE_SPINLOCK(xenoprof_lock);
-struct domain *active_domains[MAX_OPROF_DOMAINS];
-int active_ready[MAX_OPROF_DOMAINS];
-unsigned int adomains;
+static struct domain *active_domains[MAX_OPROF_DOMAINS];
+static int active_ready[MAX_OPROF_DOMAINS];
+static unsigned int adomains;
-struct domain *passive_domains[MAX_OPROF_DOMAINS];
-unsigned int pdomains;
+static struct domain *passive_domains[MAX_OPROF_DOMAINS];
+static unsigned int pdomains;
-unsigned int activated;
-struct domain *xenoprof_primary_profiler;
-int xenoprof_state = XENOPROF_IDLE;
+static unsigned int activated;
+static struct domain *xenoprof_primary_profiler;
+static int xenoprof_state = XENOPROF_IDLE;
static unsigned long backtrace_depth;
-u64 total_samples;
-u64 invalid_buffer_samples;
-u64 corrupted_buffer_samples;
-u64 lost_samples;
-u64 active_samples;
-u64 passive_samples;
-u64 idle_samples;
-u64 others_samples;
+static u64 total_samples;
+static u64 invalid_buffer_samples;
+static u64 corrupted_buffer_samples;
+static u64 lost_samples;
+static u64 active_samples;
+static u64 passive_samples;
+static u64 idle_samples;
+static u64 others_samples;
int is_active(struct domain *d)
{
return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
}
-int is_passive(struct domain *d)
+static int is_passive(struct domain *d)
{
struct xenoprof *x = d->xenoprof;
return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_PASSIVE));
}
-int is_profiled(struct domain *d)
+static int is_profiled(struct domain *d)
{
return (is_active(d) || is_passive(d));
}
static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
+ struct domain *d = current->domain;
struct xenoprof_init xenoprof_init;
int ret;
if ( copy_from_guest(&xenoprof_init, arg, 1) )
return -EFAULT;
- if ( (ret = xenoprof_arch_init(&xenoprof_init.num_events,
- &xenoprof_init.is_primary,
+ if ( (ret = xenoprof_arch_init(&xenoprof_init.num_events,
xenoprof_init.cpu_type)) )
return ret;
- if ( copy_to_guest(arg, &xenoprof_init, 1) )
- return -EFAULT;
-
+ xenoprof_init.is_primary =
+ ((xenoprof_primary_profiler == d) ||
+ ((xenoprof_primary_profiler == NULL) && (d->domain_id == 0)));
if ( xenoprof_init.is_primary )
xenoprof_primary_profiler = current->domain;
- return 0;
+ return (copy_to_guest(arg, &xenoprof_init, 1) ? -EFAULT : 0);
}
#endif /* !COMPAT */
#ifndef __ASM_XENOPROF_H__
#define __ASM_XENOPROF_H__
-int xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type);
+int xenoprof_arch_init(int *num_events, char *cpu_type);
int xenoprof_arch_reserve_counters(void);
int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
int xenoprof_arch_setup_events(void);
#ifndef __ASM_X86_XENOPROF_H__
#define __ASM_X86_XENOPROF_H__
-int nmi_init(int *num_events, int *is_primary, char *cpu_type);
int nmi_reserve_counters(void);
int nmi_setup_events(void);
int nmi_enable_virq(void);
void nmi_disable_virq(void);
void nmi_release_counters(void);
-#define xenoprof_arch_init(num_events, is_primary, cpu_type) \
- nmi_init(num_events, is_primary, cpu_type)
+int xenoprof_arch_init(int *num_events, char *cpu_type);
#define xenoprof_arch_reserve_counters() nmi_reserve_counters()
#define xenoprof_arch_setup_events() nmi_setup_events()
#define xenoprof_arch_enable_virq() nmi_enable_virq()
int xenoprof_add_trace(struct domain *d, struct vcpu *v,
unsigned long eip, int mode);
-extern struct domain *xenoprof_primary_profiler;
-
#endif /* __XEN__XENOPROF_H__ */